#!/usr/bin/env python3

import os
import sys
import json
import logging
import argparse
# Add bisect module path from LKP_SRC
sys.path.append(os.path.join(os.environ['LKP_SRC'], 'programs/bisect-py'))
from py_bisect import GitBisect
from bisect_log_config import logger

def parse_arguments():
    """Parse and validate command line arguments"""
    parser = argparse.ArgumentParser(
        description='Git bisect automation tool',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    
    # Required arguments
    parser.add_argument(
        '--bad-job-id',
        required=True,
        help='ID of the bad job to bisect'
    )
    
    # Optional arguments
    parser.add_argument(
        '--good-commit',
        help='Known good commit hash (baseline commit)'
    )
    parser.add_argument(
        '--metric',
        dest='bisect_metric',
        help='Performance metric name for bisecting performance regressions (e.g., boot-time.dhcp)'
    )
    parser.add_argument(
        '--error-id',
        help='Error identifier for bisecting functional bugs (e.g., makepkg.eid.some-error)'
    )
    parser.add_argument(
        '--result-root',
        default=None,
        help='Directory to store bisect results (default: bisect_results/JOB_ID)'
    )
    parser.add_argument(
        '--repo-dir',
        help='External Git repository directory to use (optional)'
    )
    
    args = parser.parse_args()
    
    # Validate mutual exclusivity
    if args.bisect_metric and args.error_id:
        raise ValueError("Cannot specify both --metric and --error-id")

    return args

def main():
    """Main execution flow for bisect process"""
    args = parse_arguments()
    
    # 仅保留单个实例
    gb = GitBisect()

    # 增强路径处理
    if args.result_root is None:
        args.result_root = os.path.abspath(  # 转换为绝对路径
            os.path.join('bisect_results', args.bad_job_id)
        )
    
    try:
        # 验证数据库连接（使用HTTP客户端兼容的方法）
        try:
            # 对于HTTP客户端，尝试获取job信息来验证连接
            test_job_info = gb.bisect_db.get_job_info(args.bad_job_id)
            if test_job_info is None:
                print(f"警告: 无法获取任务 {args.bad_job_id} 的信息，可能任务不存在或数据库连接有问题")
                # 不立即退出，因为任务可能确实不存在，让后续流程处理
            else:
                print(f"数据库连接正常，成功获取任务 {args.bad_job_id} 的信息")

        except Exception as e:
            print(f"数据库连接测试失败 - 坏任务ID: {args.bad_job_id} - 错误: {str(e)}")
            print("将继续执行，如果任务确实存在，后续步骤会进行处理")
            # 不立即退出，让GitBisect类的初始化流程来处理具体错误

        task = {
            'bad_job_id': args.bad_job_id,
            'good_commit': args.good_commit,
            'bisect_metric': args.bisect_metric,
            'error_id': args.error_id,
            'bisect_result_root': args.result_root
        }

        # 执行bisect - 添加仓库路径参数
        os.environ['LC_ALL'] = "C"
        result = gb.find_first_bad_commit(
            task, 
            repo_dir=args.repo_dir  # 传入外部仓库路径
        )
        
        if result:
            print(json.dumps(result, indent=4, default=str))
            return 0
        return 1

    except Exception as e:
        logger.exception(f"二分查找过程失败 - 坏任务ID: {args.bad_job_id}")
        print(f"Bisect failed: {str(e)} - 坏任务ID: {args.bad_job_id}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    try:
        sys.exit(main())
    except Exception as e:
        # 尝试获取坏任务ID
        bad_job_id = "未知"
        if hasattr(e, 'bad_job_id'):
            bad_job_id = e.bad_job_id
        elif len(sys.argv) > 1 and sys.argv[1].startswith('--bad-job-id'):
            # 尝试从命令行参数解析
            try:
                bad_job_id = sys.argv[sys.argv.index('--bad-job-id') + 1]
            except:
                pass
        
        print(f"Bisect失败: {str(e)} - 坏任务ID: {bad_job_id}", file=sys.stderr)
        sys.exit(1)
